import sys
import traceback

from xpy.aio.aio_upy import *

class aio(aio):

    def main(self,t=None,a=(),k={},**kw):
        t = getattr(__import__('__main__'),'__main__',t)

        if t:
            if self.t is None:
                self.t = t
                pdb('13: async run to %s() end' % t.__name__)
            else:
                print('resume')
                Time.sleep(.001)

        idle = kw.get('idle',None)
        if not idle:
            return self._run(self.t)

        if self.t:
            self.loop.create_task( t(*a,**k) )

        try:
            while use.lives:
                self.loop.call_soon(self.loop.stop)
                self._run()
                Time.sleep(idle)
        except RuntimeError as e:
            pdb("32:",e)
            pdb(self.__class__.loop,self.loop)
            raise

        return []

    def _run(self,t=None):
        try:
            if t:
                self.loop.run_until_complete(t)
            else:
                self.loop.run_forever()
            self.loop.close()
        except KeyboardInterrupt:
            pdb('\r\n','resume','restarts AIO loop')
        except Exception as e:
            #pdb("ERROR",e)
            sys.print_exception(e,sys.stderr)
        finally:
            return []

    begins = []
    ends = []


    #===========================================
    # dead code for non async coroutines
#
#
#    fileno = 3
#
#    def __call__(self,coroutine, hint=None):
#
#        if hint is None:
#            hint = '?'
#            try:hint= coroutine.__name__
#            except:pass
#
#        self.coroutine = coroutine
#
#        self.stdin = self.__class__.fileno
#        self.stdout = self.__class__.fileno+1
#        self.stderr = self.__class__.fileno+2
#        self.coroutine= coroutine
#        self.__class__.fileno +=3
#        self.hint = hint
#
#        #default would be native coroutine
#        self.wrapper = self.coroutine
#
#        if not __UPY__:
#            pdb("AIO Type", inspect.iscoroutinefunction( coroutine ), inspect.isawaitable( coroutine ) )
#
#
#    @classmethod
#    def io(cls):
#        if not __UPY__:
#            sys.__stdout__.flush()
#            sys.__stderr__.flush()
#
#    @classmethod
#    def start(self,coroutine,*argv,**kw):
#        try:hint = "ASync[%s]" % coroutine.__name__
#        except:hint= "ASync[%s]" % repr(coroutine)
#        RunTime.aio.Coroutines.append( [coroutine, argv, kw, hint ]  )
#
#
#    def wrap(self,*argv,**kw):
#        self.hint = 'Loop[%s]' % self.hint
#        self.wrapper = self.aio_loop
#        RunTime.aio.Coroutines.append( [self, argv, kw, self.hint ]  )
#        return self
#
#    @uasyncio.coroutine
#    def aio_task(self,argv,kw):
#        pdb("47:aio_task %s starting",self.hint)
#        try:
#            yield from self.coroutine(*argv,**kw)
#        except Exception as e:
#            Log.exception(e,"Coroutine '%s' error" % self.hint)
#            #kill task
#            return None
#
#    @uasyncio.coroutine
#    def aio_loop(self,argv,kw):
#        pdb("57:aio_loop %s starting",self.hint)
#        try:
#            while use.life:
#                self.coroutine(*argv,**kw)
#                yield from uasyncio.sleep(.0001)#self.coro(*argv,**kw)
#        except Exception as e:
#            Log.exception(e,"Coroutine '%s' error" % self.hint)
#            #kill task
#            return None
#
#    def __repr__(self):
#        return 'Coro(%s)'%self.hint
#    __str__ = __repr__
#
#




Coroutines = []

def End():
    pdb("117: aio running ends")
    while len(aio.ends):
        aio.ends.pop()()
    __import__('sys').__stdout__.write('\x1b[?1003l')
    __import__('os').system('stty sane')

#def boot(Hz=8000,run=True):
#    global begins, ends
#
#    if Coroutines:
#        while len(aio.begins):
#            aio.begins.pop(0)()
#
#        while len(Coroutines):
#            channel, argv, kw, hint = Coroutines.pop(0)
#            try:
#                if isinstance(channel, coro):
#                    pdb("130: AIO[%s]: %s with wrap handler %s started", hint, channel, channel.wrapper )
#                    RunTime.aio.loop.create_task( channel.wrapper(argv,kw) )
#                else:
#                    pdb("133: AIO[%s]: %s native async with no pty", hint, channel )
#                    RunTime.aio.loop.create_task( channel(*argv,**kw) )
#            except Exception as e:
#                Log.exception("AIO[%s] could not start"%hint)
#
#        if not run:
#            pdb("139: ====== not running aio loop, use RunTime.aio.loop and ends list =======")
#            return RunTime.aio.loop
#        try:
#            RunTime.aio.loop.run_forever()
#        except SystemExit:
#            RunTime.aio.loop.stop()
#        except KeyboardInterrupt:
#            RunTime.aio.loop.stop()
#        finally:
#            RunTime.aio.loop.close()
#            End()
#            return
#    pdb("114: No coroutines were defined")
#
#

export('asyncio', uasyncio)

if not __UPY__ and not __EMSCRIPTEN__:
    import atexit
    atexit.register(End)
else:
    pdb("165: no atexit aio.End for {}".format(sys.platform))



















#
